#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include <coroutine>
#include <future>
#include <string>
#include <sstream>

// 多线程写文件函数
void multiThreadWriteFile(const std::string& filename, int numThreads, int linesPerThread) {
    auto writeFunction = [filename](int threadId, int lines) {
        std::ofstream file(filename, std::ios::app); // 以追加模式打开文件
        if (!file.is_open()) {
            std::cerr << "Failed to open file" << std::endl;
            return;
        }
        for (int i = 0; i < lines; ++i) {
            file << "Thread " << threadId << ", Line " << i << std::endl;
        }
        file.close();
    };

    std::vector<std::thread> threads;
    for (int i = 0; i < numThreads; ++i) {
        threads.emplace_back(writeFunction, i, linesPerThread);
    }

    for (auto& t : threads) {
        if (t.joinable()) t.join();
    }
}

// 协程等待体，用于模拟异步写入
struct FileWriterAwaiter {
    std::ofstream& file;
    std::string line;

    bool await_ready() const noexcept { return false; }
    void await_suspend(std::coroutine_handle<> handle) {
        file << line << std::endl;
        handle.resume(); // 完成后恢复协程
    }
    void await_resume() {}
};

// 协程写文件结构
struct FileWriter {
    struct promise_type {
        std::ofstream file;
        FileWriter get_return_object() { 
            return FileWriter{std::coroutine_handle<promise_type>::from_promise(*this)}; 
        }
        std::suspend_always initial_suspend() { return {}; } // 初始挂起点
        std::suspend_always final_suspend() noexcept { return {}; } // 最终挂起点
        void unhandled_exception() { std::terminate(); }
        void return_void() {}

        FileWriterAwaiter yield_value(const std::string& line) {
            FileWriterAwaiter awaiter{file, line};
            return awaiter;
        }
    };

    std::coroutine_handle<promise_type> handle_;

    FileWriter(std::coroutine_handle<promise_type> h) : handle_(h) {}
    ~FileWriter() { if (handle_) handle_.destroy(); }
};

// 异步写入文件的协程函数
FileWriter asyncWriteToFile(const std::string& filename, int lines) {
    auto handle = FileWriter::promise_type{};
    handle.file.open(filename, std::ios::app);
    if (!handle.file.is_open()) {
        std::cerr << "Failed to open file" << std::endl;
        co_return; // 返回无效的协程句柄
    }
    
    co_await std::suspend_always{}; // 可选的初始挂起点
    
    for (int i = 0; i < lines; ++i) {
        co_await handle.yield_value("Line " + std::to_string(i));
    }
    
    handle.file.close();
}

// 测量性能
template<typename Func>
void measurePerformance(Func func, const std::string& description) {
    auto start = std::chrono::high_resolution_clock::now();
    func();
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << description << " took "
              << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
              << " ms" << std::endl;
}

int main() {
    std::string filename = "output.txt";
    std::remove(filename.c_str()); // 清除旧文件

    int numThreadsOrCoroutines = 4;
    int linesPerThreadOrCoroutine = 10000;

    // 测试多线程写文件
    measurePerformance(
        [&]() { multiThreadWriteFile(filename, numThreadsOrCoroutines, linesPerThreadOrCoroutine); },
        "Multi-threaded writing"
    );

    std::remove(filename.c_str()); // 清除旧文件

    // 测试多协程写文件
    measurePerformance(
        [&]() {
            std::vector<std::future<void>> futures;
            for (int i = 0; i < numThreadsOrCoroutines; ++i) {
                futures.push_back(std::async(std::launch::async, [&]() {
                    auto writer = asyncWriteToFile(filename, linesPerThreadOrCoroutine);
                    while (!writer.handle_.done()) {
                        writer.handle_.resume();
                    }
                }));
            }
            for (auto& future : futures) {
                future.get();
            }
        },
        "Co-routine writing"
    );

    return 0;
}